package suites.queue {
	import suites.queue.mock.AsyncQable;
	import suites.queue.mock.ImmediateQable;

	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertNotNull;
	import org.splink.library.queue.IQ;
	import org.splink.library.queue.IQable;
	import org.splink.library.queue.ParallelQ;
	import org.splink.library.queue.Q;

	/**
	 * @author Max Kugland
	 */
	public class ParallelQStaticsTest extends AbstractQTest {
			
		/**
		 * @inheritDoc
		 */
		override protected function qImpl(id : String) : IQ {
			return new ParallelQ(id);
		}
		
		[Test]
		public function testGetForId() : void {
			var q1 : IQ = createQ(1); //q0			var q2 : IQ = createQ(2); //q2
			q1.add(q2);
			
			_q.add(createQ(2)); // q5			_q.add(createQ(3)); // q8
			_q.add(q1);			_q.add(createQ(1)); //q12
			assertNotNull(Q.getForId(_q, "q-0"));			assertNotNull(Q.getForId(_q, "q-2"));			assertNotNull(Q.getForId(_q, "q-5"));			assertNotNull(Q.getForId(_q, "q-8"));			assertNotNull(Q.getForId(_q, "q-12"));
						assertNotNull(Q.getForId(_q, "i-1"));			assertNotNull(Q.getForId(_q, "i-3"));			assertNotNull(Q.getForId(_q, "i-4"));			assertNotNull(Q.getForId(_q, "i-6"));			assertNotNull(Q.getForId(_q, "i-7"));			assertNotNull(Q.getForId(_q, "i-9"));			assertNotNull(Q.getForId(_q, "i-10"));			assertNotNull(Q.getForId(_q, "i-11"));			assertNotNull(Q.getForId(_q, "i-13"));		}
		
		[Test]
		public function testGetTotal() : void {
			_q.add(new ImmediateQable());
			assertEquals(Q.getTotal(_q), 1);
			
			_q.add(new ImmediateQable());
			_q.add(new ImmediateQable());
			_q.add(new ImmediateQable());
			_q.add(new ImmediateQable());
			assertEquals(Q.getTotal(_q), 5);
			
			_q.add(createQ(4));
			assertEquals(Q.getTotal(_q), 10);
			
			_q.add(createQ(1));
			assertEquals(Q.getTotal(_q), 12);			
			var q1 : IQ = createQ(3);
			var q2 : IQ = createQ(2);			q1.add(q2);
			_q.add(q1);
			assertEquals(Q.getTotal(_q), 19);
			
			_q.add(new ImmediateQable());			assertEquals(Q.getTotal(_q), 20);
		}
		
		[Test]
		public function testVisit() : void {
			var q1 : IQ = createQ(3);
			var q2 : IQ = createQ(2);
			q1.add(q2);
			_q.add(new ImmediateQable());			_q.add(q1);			_q.add(new AsyncQable());
			
			var a : Array = new Array();
			Q.visit(_q, function(node : IQable) : void {
				assertNotNull(node);
				a.push(node);
			});
			
			assertEquals(a.length, Q.getTotal(_q));
			
			for each (var n : IQable in a) {
				assertEquals(n, Q.getForId(_q, n.id));
			}
		}
		
		[Test]
		public function testRemove() : void {
			var q1 : IQ = createQ(3);			var q2 : IQ = createQ(5);			var q3 : IQ = createQ(1);			var q4 : IQ = createQ(2);			var q5 : IQ = createQ(2);
			
			_q.add(q1);
			q1.add(q2);			q1.add(q3);			q3.add(q4);			q4.add(q5);
			
			assertEquals(18, Q.getTotal(_q));
			
			var toRemove : Array = new Array();
			Q.visit(_q, function(n : IQable):void {
				toRemove.unshift(n);
			});
			
			for each (var rem : IQable in toRemove) {
				var item : IQable = Q.remove(_q, rem);
				assertNotNull(item);				
			}
			
			assertEquals(0, Q.getTotal(_q));
		}
	}
}
